/**
 * 
 */

package com.pp.admin.main.client.tab;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.pp.admin.common.client.beans.BaseBean;
import com.pp.admin.common.client.beans.BaseUser;
import com.pp.admin.common.client.beans.ListContents;
import com.pp.admin.common.client.beans.PageInfo;
import com.pp.admin.common.client.helper.Action;
import com.pp.admin.common.client.helper.ActionHandler;
import com.pp.admin.common.client.helper.AdminFlexTable;
import com.pp.admin.common.client.helper.AdminImage;
import com.pp.admin.common.client.helper.DeleteHandler;
import com.pp.admin.common.client.helper.DisableAction;
import com.pp.admin.common.client.helper.Resource;
import com.pp.admin.main.client.Administrator;
import com.pp.admin.main.client.common.BaseContentsPanel;
import com.pp.admin.main.client.common.Pagination;
import com.pp.admin.main.client.common.TabListContents;

/**
 * @author pandurang
 */
class ListUserPanel extends BaseContentsPanel implements TabListContents {

	static final int LIST_HEADER_ROW = 0;

	static final int SELECT_ROW_COL = 0;

	static final int USER_NAME_COL = 1;

	static final int FIRST_NAME_COL = 2;

	static final int LAST_NAME_COL = 3;

	static final int STATUS_COL = 4;

	static final int EDIT_COL = 5;

	static final int DELETE_COL = 6;

	static final int ACTION_COL = 7;

	private CrudOnUserListPage crudOperationsTop = new CrudOnUserListPage();

	private CrudOnUserListPage crudOperationsBottom = new CrudOnUserListPage();

	private Pagination pagination = null;

	private AdminFlexTable contents = new AdminFlexTable();

	private HashSet<CheckBox> listOnPage = new HashSet<CheckBox>();

	private HashMap<String, Integer> userRowMapping = new HashMap<String, Integer>();

	ListUserPanel(UserPage parent) {
		this.setWidth("100%");
		this.setHeight("100%");
		pagination = new Pagination(this, new PageInfo());
		this.parent = parent;
		ClickHandler createHandler = ((UserPage) this.parent).new CreateHandler();
		ClickHandler deleteHandler = new DeleteHandler(myConstants.user()) {

			@Override
			public void delete(Object msg) {

				crudOperationsTop.disableDeleteAction();
				crudOperationsBottom.disableDeleteAction();
				bulkDelete();

			}
		};
		ClickHandler disableHandler = new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {

				crudOperationsTop.disableDisableAction();
				crudOperationsBottom.disableDisableAction();
				bulkDisable();

			}
		};
		ClickHandler activateHandler = new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {

				crudOperationsTop.disableActivateAction();
				crudOperationsBottom.disableActivateAction();
				bulkActivate();

			}
		};

		crudOperationsTop.addCreateClickHandler(createHandler);
		crudOperationsTop.addDeleteClickHandler(deleteHandler);
		crudOperationsBottom.addCreateClickHandler(createHandler);
		crudOperationsBottom.addDeleteClickHandler(deleteHandler);
		crudOperationsTop.addActivateClickHandler(activateHandler);
		crudOperationsBottom.addActivateClickHandler(activateHandler);
		crudOperationsTop.addDisableClickHandler(disableHandler);
		crudOperationsBottom.addDisableClickHandler(disableHandler);
		this.add(crudOperationsTop);
		contents.setStyleName("admin-list-table");
		contents.setWidget(LIST_HEADER_ROW, USER_NAME_COL, new HTML(myConstants.username()));
		contents.setWidget(LIST_HEADER_ROW, FIRST_NAME_COL, new HTML(myConstants.firstName()));
		contents.setWidget(LIST_HEADER_ROW, LAST_NAME_COL, new HTML(myConstants.lastName()));
		contents.setWidget(LIST_HEADER_ROW, STATUS_COL, new HTML(myConstants.status()));
		contents.setWidget(LIST_HEADER_ROW, EDIT_COL, new HTML(myConstants.edit()));
		contents.setWidget(LIST_HEADER_ROW, DELETE_COL, new HTML(myConstants.delete()));
		contents.setWidget(LIST_HEADER_ROW, ACTION_COL, new HTML(myConstants.action()));
		contents.getRowFormatter().addStyleName(LIST_HEADER_ROW, "admin-list-table-header");
		this.add(contents);
		this.add(pagination);

		this.setCellHorizontalAlignment(pagination, HasHorizontalAlignment.ALIGN_CENTER);
		this.add(crudOperationsBottom);
	}

	private void list() {

		crudOperationsTop.refreshState();
		crudOperationsBottom.refreshState();
		BasePage.userService.listBaseUsers(pagination.getPage(), new AsyncCallback<ListContents>() {

			@Override
			public void onSuccess(ListContents result) {

				pagination.refresh(result.getPageInfo());
				refresh(result);
			}

			@Override
			public void onFailure(Throwable caught) {

				// TODO Auto-generated method stub

			}
		});
	}

	class DeleteActionHandler extends DeleteHandler {

		public DeleteActionHandler() {

			super(myConstants.user());
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.pp.admin.common.client.helper.DeleteHandler#delete(java.lang.
		 * Object)
		 */
		@Override
		public void delete(Object msg) {

			deleteUser((String) msg);

		}

	}

	class ActivateActionHandler implements ActionHandler {

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.pp.admin.common.client.helper.ActionHandler#action(java.lang.
		 * String)
		 */
		@Override
		public void action(String objectID) {

			activate(objectID);

		}

	}

	class DisableActionHandler implements ActionHandler {

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.pp.admin.common.client.helper.ActionHandler#action(java.lang.
		 * String)
		 */
		@Override
		public void action(String objectID) {

			disable(objectID);

		}

	}

	private void refresh(ListContents listContents) {
		listOnPage = new HashSet<CheckBox>();
		Iterator<BaseBean> itrBaseUsers = listContents.getContents().iterator();
		BaseUser baseUser = null;
		if (contents.getRowCount() > 1) {
			int rowCount = contents.getRowCount();
			for (int index = rowCount - 1; index > 0; index--) {
				contents.removeRow(index);
			}
		}
		int rowCount = 1;
		ActivateActionHandler activateHandler = new ActivateActionHandler();
		DeleteActionHandler deleteHandler = new DeleteActionHandler();
		DisableActionHandler disableHandler = new DisableActionHandler();
		ActionHandler editHandler = ((UserPage) this.parent).new EditClickHandler();
		while (itrBaseUsers.hasNext()) {
			boolean currentUser = false;
			baseUser = (BaseUser) itrBaseUsers.next();
			userRowMapping.put(baseUser.getUserID(), rowCount);
			if (Administrator.getCurrentUserInfo().getUserID().equalsIgnoreCase(baseUser.getUserID())) {
				currentUser = true;
			} else {
				CheckBox chkBox = new CheckBox();
				chkBox.setFormValue(baseUser.getUserID());
				listOnPage.add(chkBox);
				contents.setWidget(rowCount, SELECT_ROW_COL, chkBox);
			}
			contents.setWidget(rowCount, USER_NAME_COL, new HTML(baseUser.getUserID()));
			contents.setWidget(rowCount, FIRST_NAME_COL, new HTML(baseUser.getFirstName()));
			contents.setWidget(rowCount, LAST_NAME_COL, new HTML(baseUser.getLastName()));
			String status = null;
			if (baseUser.getStatus() == BaseUser.STATUS_ACTIVE) {
				status = myConstants.active();
			} else if (baseUser.getStatus() == BaseUser.STATUS_DELETED) {
				status = myConstants.disabled();
			} else if (baseUser.getStatus() == BaseUser.STATUS_REQUESTED) {
				status = myConstants.requsted();
			}
			contents.setWidget(rowCount, STATUS_COL, new HTML(status));
			AdminImage editimg = null;
			if (currentUser) {
				editimg = new DisableAction(Resource.DISABLE_EDIT_IMG_URL);
			} else {
				Action edit = new Action(editHandler, Resource.EDIT_IMG_URL);
				edit.setValue(baseUser.getUserID());
				editimg = edit;
			}
			contents.setWidget(rowCount, EDIT_COL, editimg);

			AdminImage deleteimg = null;
			if (currentUser) {
				deleteimg = new DisableAction(Resource.DISABLE_DELETE_IMG_URL);
			} else {
				Action delete = new Action(deleteHandler, Resource.DELETE_IMG_URL);
				delete.setValue(baseUser.getUserID());
				deleteimg = delete;
			}
			contents.setWidget(rowCount, DELETE_COL, deleteimg);
			if (baseUser.getStatus() == BaseUser.STATUS_ACTIVE) {
				AdminImage disableimg = null;
				if (currentUser) {
					disableimg = new DisableAction(Resource.DISABLE_DISABLE_IMG_URL);
				} else {
					Action disable = new Action(disableHandler, Resource.DISABLE_IMG_URL);
					disable.setValue(baseUser.getUserID());
					disableimg = disable;
				}
				contents.setWidget(rowCount, ACTION_COL, disableimg);
			} else {
				AdminImage activateimg = null;
				if (currentUser) {
					activateimg = new DisableAction(Resource.DISABLE_OK_IMG_URL);
				} else {
					Action activate = new Action(activateHandler, Resource.OK_IMG_URL);
					activate.setValue(baseUser.getUserID());
					activateimg = activate;
				}
				contents.setWidget(rowCount, ACTION_COL, activateimg);

			}
			rowCount++;
		}

	}

	public List<String> getSelectedUserIDs() {

		CheckBox row = null;
		List<String> userIds = new ArrayList<String>();
		for (Iterator<CheckBox> iterator = listOnPage.iterator(); iterator.hasNext();) {
			row = iterator.next();
			if (row.getValue()) {
				userIds.add(row.getFormValue());
			}
		}
		return userIds;
	}

	void bulkDelete() {

		deleteData(getSelectedUserIDs());
	}

	void bulkActivate() {

		activateData(getSelectedUserIDs());
	}

	void bulkDisable() {

		disableData(getSelectedUserIDs());
	}

	@Override
	public void refresh() {

		list();
	}

	public void edit(String objectID) {

		this.add(new HTML("Edit => " + objectID));

	}

	private void deleteData(List<String> userIDs) {

		for (Iterator<String> iterator = userIDs.iterator(); iterator.hasNext();) {
			AdminImage disableimg = new DisableAction(Resource.DISABLE_DELETE_IMG_URL);
			contents.setWidget(userRowMapping.get(iterator.next()), DELETE_COL, disableimg);

		}
		userService.deleteUsers(userIDs, new AsyncCallback<Void>() {

			@Override
			public void onFailure(Throwable caught) {

				// TODO Auto-generated method stub

			}

			@Override
			public void onSuccess(Void result) {

				list();

			}
		});

	}

	public void deleteUser(String objectID) {

		List<String> userIds = new ArrayList<String>();
		userIds.add(objectID);
		deleteData(userIds);
	}

	public void activateData(List<String> userIDs) {

		for (Iterator<String> iterator = userIDs.iterator(); iterator.hasNext();) {
			AdminImage disableimg = new DisableAction(Resource.DISABLE_OK_IMG_URL);
			contents.setWidget(userRowMapping.get(iterator.next()), ACTION_COL, disableimg);
		}
		userService.activateUsers(userIDs, new AsyncCallback<Void>() {

			@Override
			public void onFailure(Throwable caught) {

				// TODO Auto-generated method stub

			}

			@Override
			public void onSuccess(Void result) {

				list();

			}
		});
	}

	public void activate(String objectID) {

		List<String> userIds = new ArrayList<String>();
		userIds.add(objectID);

		activateData(userIds);
	}

	public void disableData(List<String> userIDs) {

		for (Iterator<String> iterator = userIDs.iterator(); iterator.hasNext();) {
			AdminImage disableimg = new DisableAction(Resource.DISABLE_DISABLE_IMG_URL);
			contents.setWidget(userRowMapping.get(iterator.next()), ACTION_COL, disableimg);

		}
		userService.disableUsers(userIDs, new AsyncCallback<Void>() {

			@Override
			public void onFailure(Throwable caught) {

				// TODO Auto-generated method stub

			}

			@Override
			public void onSuccess(Void result) {

				list();

			}
		});
	}

	public void disable(String objectID) {

		List<String> userIds = new ArrayList<String>();
		userIds.add(objectID);
		disableData(userIds);

	}

}
